'    Copyright 2008 Jan Molnar <jan.molnar@abds.de>
'
'    This file is part of JCQ.

'    JCQ is free software: you can redistribute it and/or modify
'    it under the terms of the GNU General Public License as published by
'    the Free Software Foundation, either version 2 of the License, or
'    (at your option) any later version.

'    JCQ is distributed in the hope that it will be useful,
'    but WITHOUT ANY WARRANTY; without even the implied warranty of
'    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
'    GNU General Public License for more details.

'    You should have received a copy of the GNU General Public License
'    along with JCQ. If not, see <http://www.gnu.org/licenses/>.

Imports System.Linq

Public Class ListOfByteFormatter
    Inherits JCsTools.Xml.Formatter.DefaultReferenceFormatter

    Public Sub New(ByVal parent As JCsTools.Xml.Formatter.ISerializer)
        MyBase.New(parent, GetType(List(Of Byte)))
    End Sub

    Protected Overrides Function CreateObject(ByVal type As System.Type, ByVal reader As System.Xml.XmlReader) As Object
        Return New List(Of Byte)
    End Function

    Public Overrides Function Deserialize(ByVal reader As System.Xml.XmlReader) As Object
        Dim objectId As Integer
        Dim type As Type
        Dim obj As Object
        Dim list As List(Of Byte)

        reader.MoveToFirstAttribute() ' This is always __id
        objectId = GetObjectId(reader)

        reader.MoveToNextAttribute() ' This is always __type
        type = GetObjectType(reader)

        obj = CreateObject(type, reader)
        list = DirectCast(obj, List(Of Byte))

        reader.Read() ' Element <data>

        Dim buffer() As Byte
        Dim bufferSize As Integer = 1024
        Dim bytesRead As Integer

        Do
            buffer = New Byte(bufferSize - 1) {}
            bytesRead = reader.ReadElementContentAsBase64(buffer, 0, bufferSize)
            If bytesRead = 0 Then Exit Do

            list.AddRange(buffer.Take(bytesRead))
        Loop

        ' The last call of ReadElementContentAsBase64 moves the reader to </listofbyte>
        ' which is already the end of the current element. no further movement is required.

        Serializer.RegisterObject(objectId, obj)

        Return obj
    End Function

    Public Overrides Sub Serialize(ByVal graph As Object, ByVal writer As System.Xml.XmlWriter)
        Dim list As List(Of Byte) = DirectCast(graph, List(Of Byte))

        writer.WriteStartElement("listofbyte")

        WriteIdAttribute(graph, writer)
        WriteTypeAttribute(graph, writer)

        writer.WriteStartElement("data")
        writer.WriteBase64(list.ToArray, 0, list.Count)
        writer.WriteEndElement()

        writer.WriteEndElement()
    End Sub

End Class